package pl.bizuteria.sklep.server.service;

import java.util.List;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import pl.bizuteria.sklep.api.product.IProductService;
import pl.bizuteria.sklep.api.product.Product;

import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyService;
import com.googlecode.objectify.Query;

public abstract class ProductService<E extends Product> implements
		IProductService<E> {

	Logger logger = LoggerFactory.getLogger(ProductService.class);

	protected Class<E> clazz;

	public ProductService(Class<E> clazz) {
		this.clazz = clazz;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see pl.bizuteria.sklep.api.product.IProductService#findAll()
	 */
	@Override
	public List<E> findAll() {
		logger.info("FindAllElements start");
		Objectify ofy = ObjectifyService.begin();
		Query<E> query = ofy.query(clazz);
		List<E> list = query.list();
		logger.info("AllElements result = " + list);
		return list;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see pl.bizuteria.sklep.api.product.IProductService#findAll(int, int)
	 */
	@Override
	public List<E> findAll(int start, int length) {
		Objectify ofy = ObjectifyService.begin();
		Query<E> query = ofy.query(clazz);
		List<E> list = query.list();
		logger.info("Find all from:  " + start + " length: " + length
				+ " elements: " + list);
		List<E> result = list.subList(start,
				Math.min(start + length, list.size()));
		logger.info("Result = " + result);
		return result;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see pl.bizuteria.sklep.api.product.IProductService#persist(E)
	 */
	@Override
	public void persist(E newEntity) {
		logger.info("Persist Start");
		logger.info("entity: " + newEntity);

		Objectify ofy = ObjectifyService.begin();

		try {
			ofy.put(newEntity);
		} catch (Exception e) {
			e.printStackTrace();
		}

		logger.info("Added entity: " + newEntity);

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see pl.bizuteria.sklep.api.product.IProductService#remove(E)
	 */
	@Override
	public void remove(E entity) {
		logger.info("Remove start " + entity);
		Objectify ofy = ObjectifyService.begin();
		ofy.delete(entity);
		logger.info("remove End");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see pl.bizuteria.sklep.api.product.IProductService#remove(java.util.Set)
	 */
	@Override
	public void remove(Set<E> elements) {
		logger.info("Remove set Start");
		logger.info("Elements: " + elements);
		Objectify ofy = ObjectifyService.begin();
		ofy.delete(elements);
		logger.info("Remove set End");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see pl.bizuteria.sklep.api.product.IProductService#count()
	 */
	@Override
	public Integer count() {
		logger.debug("Count Start");
		int size = findAll().size();
		logger.debug("Size = " + size);
		return size;
	}

}
